/*
 * @Author: fuhongliang-TSJ hongliang.fu@4d-bios.com
 * @Date: 2025-10-10 10:09:26
 * @LastEditTime: 2025-10-11 14:47:17
 * @LastEditors: fuhongliang-TSJ hongliang.fu@4d-bios.com
 * @Description: 
 * @FilePath: \lc_-esp32_-s3\main\lc\handheld\wifi_app.c
 * 立创实战派ESP32-S3开发板
 * Copyright (c) 2025 by 4D Bios, All Rights Reserved. 
 */

#include <time.h>
#include <sys/time.h>
#include "handheld.h"
#include "sntp.h"
#include "bsp_lvgl.h"
#include "esp_sntp.h"
#include "esp_netif_sntp.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"

static const char *TAG = "wifi_app";

extern int icon_flag;
extern lv_obj_t *main_obj; // 主界面
extern lv_obj_t *main_text_label; // 主界面 欢迎语

static lv_obj_t *wifi_scan_page;     // wifi扫描页面 obj
static lv_obj_t *wifi_connect_page;  // wifi连接页面 obj
static lv_obj_t *wifi_password_page; // wifi密码页面 obj
static lv_obj_t *wifi_list;          // wifi列表  list
static lv_obj_t *label_wifi_connect; // wifi连接页面label 
static lv_obj_t *ta_pass_text;       // 密码输入文本框 textarea
static lv_obj_t *roller_num;         // 数字roller
static lv_obj_t *roller_letter_low;  // 小写字母roller
static lv_obj_t *roller_letter_up;   // 大写字母roller
static lv_obj_t *label_wifi_name;    // wifi名称label
static lv_obj_t *label_wifi_scan;    // wif扫描页面 label
static lv_obj_t *obj_title;          // 标题 obj

static lv_obj_t * date_label;        //日期标签
static lv_obj_t * time_label;        //时间标签

static time_t now;
static struct tm timeinfo;

// 声明使用的字体
LV_FONT_DECLARE(font_alipuhui20);
LV_FONT_DECLARE(font_awesome);

#define DEFAULT_SCAN_LIST_SIZE   10                // 最大扫描wifi个数

// wifi事件组
static EventGroupHandle_t s_wifi_event_group = NULL;

// wifi事件
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT      BIT1
#define WIFI_START_BIT     BIT2
#define WIFI_GET_SNTP_BIT  BIT3

// wifi最大重连次数
#define EXAMPLE_ESP_MAXIMUM_RETRY  3

// wifi账号队列
static QueueHandle_t xQueueWifiAccount = NULL;

// 队列要传输的内容
typedef struct {
    char wifi_ssid[32];  // 获取wifi名称
    char wifi_password[64]; // 获取wifi密码    
    char back_flag; // 是否退出     
} wifi_account_t;

static void event_handler(void* arg, esp_event_base_t event_base,
                                int32_t event_id, void* event_data)
{
    static int s_retry_num = 0;
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
         xEventGroupSetBits(s_wifi_event_group, WIFI_START_BIT);
         s_retry_num = 0;
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGI(TAG, "retry to connect to the AP");
        } else {
            xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
        }
        ESP_LOGI(TAG,"connect to the AP fail");
    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
        ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
        s_retry_num = 0;
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
    }
}

esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
esp_netif_t *sta_netif = NULL;

// 扫描附近wifi
static void wifi_scan(wifi_ap_record_t ap_info[], uint16_t *ap_number)
{
    s_wifi_event_group = xEventGroupCreate();

    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    sta_netif = esp_netif_create_default_wifi_sta();
    assert(sta_netif);

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
                                                        ESP_EVENT_ANY_ID,
                                                        &event_handler,
                                                        NULL,
                                                        &instance_any_id));
    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
                                                        IP_EVENT_STA_GOT_IP,
                                                        &event_handler,
                                                        NULL,
                                                        &instance_got_ip));

    uint16_t number = *ap_number;
    uint16_t ap_count = 0;
    memset(ap_info, 0, number * sizeof(wifi_ap_record_t));

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_start());
    esp_wifi_scan_start(NULL, true);

    ESP_LOGI(TAG, "Max AP number ap_info can hold = %u", *ap_number);
    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count));                 // 获取扫描到的wifi数量
    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(ap_number, ap_info));    // 获取真实的获取到wifi数量和信息
    ESP_LOGI(TAG, "Total APs scanned = %u, actual AP number ap_info holds = %u", ap_count, *ap_number);
}

// 清除wifi初始化内容
static void wifiset_deinit(void)
{
    ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &instance_any_id));
    ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &instance_got_ip));
    esp_err_t err = esp_wifi_stop();
    if (err == ESP_ERR_WIFI_NOT_INIT) {
        return;
    }
    ESP_ERROR_CHECK(err);
    ESP_ERROR_CHECK(esp_wifi_deinit());
    ESP_ERROR_CHECK(esp_wifi_clear_default_wifi_driver_and_handlers(sta_netif));
    esp_netif_destroy(sta_netif);
    sta_netif = NULL;
    ESP_ERROR_CHECK(esp_event_loop_delete_default());
}

/**
 * @description: wifi连接界面显示
 * @return {*}
 */
static void lv_wifi_connect(void)
{
    lv_obj_del(wifi_password_page); // 删除密码输入界面

    //创建wifi连接界面
    wifi_connect_page = lv_obj_create(lv_scr_act());
    lv_obj_set_size(wifi_password_page, 320, 240);
    lv_obj_set_style_border_width(wifi_password_page, 0 , 0); //边框宽度0
    lv_obj_set_style_pad_all(wifi_password_page, 0 , 0);      //内间距0
    lv_obj_set_style_radius(wifi_password_page, 0, 0);        // 圆角半径0

    label_wifi_connect = lv_label_create(wifi_connect_page);
    lv_label_set_text(label_wifi_connect, "WLAN连接中...");
    lv_obj_set_style_text_font(label_wifi_connect, &font_alipuhui20, 0);
    lv_obj_align(label_wifi_connect, LV_ALIGN_CENTER, 0, -50);
}

/**
 * @description: "连接按钮" 返回函数
 * @param {lv_event_t *} e
 * @return {*}
 */
static void btn_connect_cb(lv_event_t * e)
{
    const char *wifi_name = NULL;
    const char *wifi_password = NULL;
    lv_event_code_t code = lv_event_get_code(e);

    if (code == LV_EVENT_CLICKED) {
        ESP_LOGI(TAG, "OK Clicked");
        wifi_name = lv_label_get_text(label_wifi_name);
        wifi_password = lv_textarea_get_text(ta_pass_text);

        if (*wifi_password != '\0') // 判断是否为空字符串
        {
            wifi_account_t wifi_account;
            strcpy(wifi_account.wifi_ssid, wifi_name);
            strcpy(wifi_account.wifi_password, wifi_password);
            ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
                wifi_account.wifi_ssid, wifi_account.wifi_password);
            wifi_account.back_flag = 0; // 正常连接
            lv_wifi_connect(); // 显示wifi连接界面
            // 发送WiFi账号密码信息到队列
            xQueueSend(xQueueWifiAccount, &wifi_account, portMAX_DELAY);
        }
    }
}

/**
 * @description: "返回按钮" 返回函数
 * @param {lv_event_t *} e
 * @return {*}
 */
static void btn_back_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    // lv_obj_t *btn = lv_event_get_target(e);
    if (code == LV_EVENT_CLICKED) {
        ESP_LOGI(TAG, "Btn-Back Clicked");
        lv_obj_del(wifi_password_page);
    }
}

/**
 * @description: "删除按钮" 返回函数
 * @param {lv_event_t *} e
 * @return {*}
 */
static void btn_del_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    // lv_obj_t *btn = lv_event_get_target(e);
    if (code == LV_EVENT_CLICKED) {
        ESP_LOGI(TAG, "Btn-Del Clicked");
        lv_textarea_del_char(ta_pass_text);
    }
}

/**
 * @description: "数字"roller 的确认键返回函数
 * @param {lv_event_t *} e
 * @return {*}
 */
static void btn_num_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    // lv_obj_t *btn = lv_event_get_target(e);
    if (code == LV_EVENT_CLICKED) {
        ESP_LOGI(TAG, "Btn-Num Clicked");
        char buf[2]; // 接收roller的值
        lv_roller_get_selected_str(roller_num, buf, sizeof(buf));
        lv_textarea_add_text(ta_pass_text, buf);
    }
}

/**
 * @description: "小写字母"roller 的确认键返回函数
 * @param {lv_event_t *} e
 * @return {*}
 */
static void btn_letter_low_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    // lv_obj_t *btn = lv_event_get_target(e);
    if (code == LV_EVENT_CLICKED) {
        ESP_LOGI(TAG, "Btn-Letter-Low Clicked");
        char buf[2]; // 接收roller的值
        lv_roller_get_selected_str(roller_letter_low, buf, sizeof(buf));
        lv_textarea_add_text(ta_pass_text, buf);
    }
}

/**
 * @description: "da写字母"roller 的确认键返回函数
 * @param {lv_event_t *} e
 * @return {*}
 */
static void btn_letter_up_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    // lv_obj_t *btn = lv_event_get_target(e);
    if (code == LV_EVENT_CLICKED) {
        ESP_LOGI(TAG, "Btn-Letter-Up Clicked");
        char buf[2]; // 接收roller的值
        lv_roller_get_selected_str(roller_letter_up, buf, sizeof(buf));
        lv_textarea_add_text(ta_pass_text, buf);
    }
}

// 密码roller的遮罩显示效果
static void mask_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * obj = lv_event_get_target(e);

    static int16_t mask_top_id = -1;
    static int16_t mask_bottom_id = -1;

    if(code == LV_EVENT_COVER_CHECK) {
        lv_event_set_cover_res(e, LV_COVER_RES_MASKED);
    }
    else if(code == LV_EVENT_DRAW_MAIN_BEGIN) {
        /* add mask */
        const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN);
        lv_coord_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN);
        lv_coord_t font_h = lv_font_get_line_height(font);

        lv_area_t roller_coords;
        lv_obj_get_coords(obj, &roller_coords);

        lv_area_t rect_area;
        rect_area.x1 = roller_coords.x1;
        rect_area.x2 = roller_coords.x2;
        rect_area.y1 = roller_coords.y1;
        rect_area.y2 = roller_coords.y1 + (lv_obj_get_height(obj) - font_h - line_space) / 2;

        lv_draw_mask_fade_param_t * fade_mask_top = lv_mem_buf_get(sizeof(lv_draw_mask_fade_param_t));
        lv_draw_mask_fade_init(fade_mask_top, &rect_area, LV_OPA_TRANSP, rect_area.y1, LV_OPA_COVER, rect_area.y2);
        mask_top_id = lv_draw_mask_add(fade_mask_top, NULL);

        rect_area.y1 = rect_area.y2 + font_h + line_space - 1;
        rect_area.y2 = roller_coords.y2;

        lv_draw_mask_fade_param_t * fade_mask_bottom = lv_mem_buf_get(sizeof(lv_draw_mask_fade_param_t));
        lv_draw_mask_fade_init(fade_mask_bottom, &rect_area, LV_OPA_COVER, rect_area.y1, LV_OPA_TRANSP, rect_area.y2);
        mask_bottom_id = lv_draw_mask_add(fade_mask_bottom, NULL);

    }
    else if(code == LV_EVENT_DRAW_POST_END) {
        lv_draw_mask_fade_param_t * fade_mask_top = lv_draw_mask_remove_id(mask_top_id);
        lv_draw_mask_fade_param_t * fade_mask_bottom = lv_draw_mask_remove_id(mask_bottom_id);
        lv_draw_mask_free_param(fade_mask_top);
        lv_draw_mask_free_param(fade_mask_bottom);
        lv_mem_buf_release(fade_mask_top);
        lv_mem_buf_release(fade_mask_bottom);
        mask_top_id = -1;
        mask_bottom_id = -1;
    }
}

/**
 * @description: 进入输入密码任务
 * @param {lv_event_t *} e
 * @return {*}
 */
static void list_btn_cb(lv_event_t * e)
{
    const char *wifi_name = NULL;
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *btn = lv_event_get_target(e);
    if (code == LV_EVENT_CLICKED)
    {
        wifi_name = lv_list_get_btn_text(wifi_list, btn);
    }

    //创建密码输入界面
    wifi_password_page = lv_obj_create(lv_scr_act());
    lv_obj_set_size(wifi_password_page, 320, 240);
    lv_obj_set_style_border_width(wifi_password_page, 0 , 0); //边框宽度0
    lv_obj_set_style_pad_all(wifi_password_page, 0 , 0);      //内间距0
    lv_obj_set_style_radius(wifi_password_page, 0, 0);        // 圆角半径0

    //创建返回按钮
    lv_obj_t *btn_back = lv_btn_create(wifi_password_page);
    lv_obj_set_size(btn_back, 60, 40);
    lv_obj_align(btn_back,LV_ALIGN_TOP_LEFT, 0, 0);
    lv_obj_set_style_border_width(btn_back, 0 , 0); //边框宽度0
    lv_obj_set_style_pad_all(btn_back, 0 , 0);      //内间距0
    lv_obj_set_style_bg_opa(btn_back, LV_OPA_TRANSP, LV_PART_MAIN);      //背景透明
    lv_obj_set_style_shadow_opa(btn_back, LV_OPA_TRANSP, LV_PART_MAIN);  //阴影透明
    lv_obj_add_event_cb(btn_back, btn_back_cb, LV_EVENT_CLICKED, NULL);

    // 按键上显示左箭头符号
    lv_obj_t *label_back = lv_label_create(btn_back);
    lv_obj_align(label_back,LV_ALIGN_TOP_LEFT, 10, 10);
    lv_label_set_text(label_back,LV_SYMBOL_LEFT);
    lv_obj_set_style_text_font(label_back, &lv_font_montserrat_16, 0);
    lv_obj_set_style_text_color(label_back, lv_color_hex(0x000000), 0);

    // 显示选中的wifi名称
    label_wifi_name = lv_label_create(wifi_password_page);
    lv_obj_align(label_wifi_name,LV_ALIGN_TOP_MID, 0, 10);
    lv_obj_set_style_text_font(label_wifi_name, &lv_font_montserrat_20, 0);
    lv_label_set_text(label_wifi_name,wifi_name);

    // 创建密码输入框
    ta_pass_text = lv_textarea_create(wifi_password_page);
    lv_textarea_set_one_line(ta_pass_text, true);                 // 一行显示
    lv_textarea_set_password_mode(ta_pass_text, false);           // 是否使用密码输入显示模式
    lv_textarea_set_placeholder_text(ta_pass_text, "password");   // 设置提醒词
    lv_obj_set_style_text_font(ta_pass_text, &lv_font_montserrat_20, 0);
    lv_obj_set_width(ta_pass_text, 150);
    lv_obj_align(ta_pass_text,LV_ALIGN_TOP_LEFT, 10, 40);
    lv_obj_add_state(ta_pass_text, LV_STATE_FOCUSED);

    // 创建“连接按钮”
    lv_obj_t *btn_connect = lv_btn_create(wifi_password_page);
    lv_obj_set_width(btn_connect, 65);
    lv_obj_align(btn_connect,LV_ALIGN_TOP_LEFT, 170, 40);
    lv_obj_add_event_cb(btn_connect, btn_connect_cb, LV_EVENT_CLICKED, NULL);

    lv_obj_t *label_ok = lv_label_create(btn_connect);
    lv_label_set_text(label_ok, "OK");
    lv_obj_set_style_text_font(label_ok, &lv_font_montserrat_20, 0);
    lv_obj_align(label_ok,LV_ALIGN_CENTER, 0, 0);

    //创建"删除按钮"
    lv_obj_t *btn_del = lv_btn_create(wifi_password_page);
    lv_obj_set_width(btn_del, 65);
    lv_obj_align(btn_del,LV_ALIGN_TOP_LEFT, 245, 40);
    lv_obj_add_event_cb(btn_del, btn_del_cb, LV_EVENT_CLICKED, NULL);

    lv_obj_t *label_del = lv_label_create(btn_del);
    lv_label_set_text(label_del, LV_SYMBOL_BACKSPACE);
    lv_obj_set_style_text_font(label_del, &lv_font_montserrat_20, 0);
    lv_obj_center(label_del);

    //创建roller样式
    static lv_style_t style;
    lv_style_init(&style);
    lv_style_set_bg_color(&style,lv_color_black());
    lv_style_set_text_color(&style,lv_color_white());
    lv_style_set_border_width(&style, 0);       // 边框宽度0
    lv_style_set_pad_all(&style, 0);            // 内间距0
    lv_style_set_radius(&style, 0);             // 圆角半径0

    // 创建"数字"roller
    const char *opts_num = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n@";

    roller_num = lv_roller_create(wifi_password_page);
    lv_obj_add_style(roller_num, &style, 0);
    lv_obj_set_style_opa(roller_num, LV_OPA_50, LV_PART_SELECTED);
    lv_roller_set_options(roller_num, opts_num, LV_ROLLER_MODE_INFINITE);  //无限循环模式
    lv_roller_set_visible_row_count(roller_num, 3);      // 显示3行
    lv_roller_set_selected(roller_num, 5, LV_ANIM_OFF);   // 默认选择
    lv_obj_set_width(roller_num, 90);
    lv_obj_set_style_text_font(roller_num, &lv_font_montserrat_20, 0);
    lv_obj_align(roller_num, LV_ALIGN_BOTTOM_LEFT, 15, -53);
    lv_obj_add_event_cb(roller_num, mask_event_cb, LV_EVENT_ALL, NULL); // 事件处理函数

    // 创建"数字"roller 的确认键
    lv_obj_t *btn_num_ok = lv_btn_create(wifi_password_page);
    lv_obj_set_width(btn_num_ok, 90);
    lv_obj_align(btn_num_ok,LV_ALIGN_BOTTOM_LEFT, 15, -10);
    lv_obj_add_event_cb(btn_num_ok, btn_num_cb, LV_EVENT_CLICKED, NULL);

    lv_obj_t *label_num_ok = lv_label_create(btn_num_ok);
    lv_label_set_text(label_num_ok, LV_SYMBOL_OK);
    lv_obj_set_style_text_font(label_num_ok, &lv_font_montserrat_20, 0);
    lv_obj_center(label_num_ok);

    // 创建"小写字母"roller
    const char *opts_letter_low = "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\no\np\nq\nr\ns\nt\nu\nv\nw\nx\ny\nz";

    roller_letter_low = lv_roller_create(wifi_password_page);
    lv_obj_add_style(roller_letter_low, &style, 0);
    lv_obj_set_style_opa(roller_letter_low, LV_OPA_50, LV_PART_SELECTED);
    lv_roller_set_options(roller_letter_low, opts_letter_low, LV_ROLLER_MODE_INFINITE);  //无限循环模式
    lv_roller_set_visible_row_count(roller_letter_low, 3);      // 显示3行
    lv_roller_set_selected(roller_letter_low, 15, LV_ANIM_OFF);   // 默认选择
    lv_obj_set_width(roller_letter_low, 90);
    lv_obj_set_style_text_font(roller_letter_low, &lv_font_montserrat_20, 0);
    lv_obj_align(roller_letter_low, LV_ALIGN_BOTTOM_LEFT, 115, -53);
    lv_obj_add_event_cb(roller_letter_low, mask_event_cb, LV_EVENT_ALL, NULL); // 事件处理函数

    // 创建"小写字母"roller 的确认键
    lv_obj_t *btn_letter_low_ok = lv_btn_create(wifi_password_page);
    lv_obj_set_width(btn_letter_low_ok, 90);
    lv_obj_align(btn_letter_low_ok,LV_ALIGN_BOTTOM_LEFT, 115, -10);
    lv_obj_add_event_cb(btn_letter_low_ok, btn_letter_low_cb, LV_EVENT_CLICKED, NULL);

    lv_obj_t *label_letter_low_ok = lv_label_create(btn_letter_low_ok);
    lv_label_set_text(label_letter_low_ok, LV_SYMBOL_OK);
    lv_obj_set_style_text_font(label_letter_low_ok, &lv_font_montserrat_20, 0);
    lv_obj_center(label_letter_low_ok);

    // 创建"大写字母"roller
    const char *opts_letter_up = "A\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ";

    roller_letter_up = lv_roller_create(wifi_password_page);
    lv_obj_add_style(roller_letter_up, &style, 0);
    lv_obj_set_style_opa(roller_letter_up, LV_OPA_50, LV_PART_SELECTED);
    lv_roller_set_options(roller_letter_up, opts_letter_up, LV_ROLLER_MODE_INFINITE);  //无限循环模式
    lv_roller_set_visible_row_count(roller_letter_up, 3);      // 显示3行
    lv_roller_set_selected(roller_letter_up, 15, LV_ANIM_OFF);   // 默认选择
    lv_obj_set_width(roller_letter_up, 90);
    lv_obj_set_style_text_font(roller_letter_up, &lv_font_montserrat_20, 0);
    lv_obj_align(roller_letter_up, LV_ALIGN_BOTTOM_LEFT, 215, -53);
    lv_obj_add_event_cb(roller_letter_up, mask_event_cb, LV_EVENT_ALL, NULL); // 事件处理函数

    // 创建"大写字母"roller 的确认键
    lv_obj_t *btn_letter_up_ok = lv_btn_create(wifi_password_page);
    lv_obj_set_width(btn_letter_up_ok, 90);
    lv_obj_align(btn_letter_up_ok,LV_ALIGN_BOTTOM_LEFT, 215, -10);
    lv_obj_add_event_cb(btn_letter_up_ok, btn_letter_up_cb, LV_EVENT_CLICKED, NULL);

    lv_obj_t *label_letter_up_ok = lv_label_create(btn_letter_up_ok);
    lv_label_set_text(label_letter_up_ok, LV_SYMBOL_OK);
    lv_obj_set_style_text_font(label_letter_up_ok, &lv_font_montserrat_20, 0);
    lv_obj_center(label_letter_up_ok);
}

// 更新时间函数
void value_update_cb(lv_timer_t * timer)
{
    // 更新日期 星期 时分秒
    time(&now);
    localtime_r(&now, &timeinfo);
    lv_label_set_text_fmt(time_label, "%02d:%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
    lv_label_set_text_fmt(date_label, "%d年%02d月%02d日", timeinfo.tm_year+1900, timeinfo.tm_mon+1, timeinfo.tm_mday);
}

// 获得日期时间 任务函数
static void get_time_task(void *pvParameters)
{
    xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT, pdFALSE, pdFALSE, portMAX_DELAY);

    //获取SNTP时间
    initialize_sntp();
    while(netif_sntp_sync() != ESP_OK);
    esp_netif_sntp_deinit();

    // 获取系统时间
    time(&now);
    localtime_r(&now, &timeinfo);

    lvgl_port_lock(0);
    lv_obj_del(main_text_label); // 删除主页的欢迎语 
    
    // 显示年月日
    date_label = lv_label_create(main_obj);
    lv_obj_set_style_text_font(date_label, &font_alipuhui20, 0);
    lv_obj_set_style_text_color(date_label, lv_color_hex(0xffffff), 0); 
    lv_label_set_text_fmt(date_label, "%d年%02d月%02d日", timeinfo.tm_year+1900, timeinfo.tm_mon+1, timeinfo.tm_mday);
    lv_obj_align(date_label, LV_ALIGN_TOP_LEFT, 10, 5);

    // 显示时间  小时:分钟:秒钟
    time_label = lv_label_create(main_obj);
    lv_obj_set_style_text_font(time_label, &font_alipuhui20, 0);
    lv_obj_set_style_text_color(time_label, lv_color_hex(0xffffff), 0); 
    lv_label_set_text_fmt(time_label, "%02d:%02d:%02d", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
    lv_obj_align_to(time_label, date_label, LV_ALIGN_OUT_RIGHT_MID, 10, 0);
    lvgl_port_unlock();

    xEventGroupSetBits(s_wifi_event_group, WIFI_GET_SNTP_BIT);

    lv_timer_create(value_update_cb, 1000, NULL);  // 创建一个lv_timer 每秒更新一次时间
    
    vTaskDelete(NULL);
}

/**
 * @description: wifi连接任务
 * @param {void} *arg
 * @return {*}
 */
static void wifi_connect(void *arg)
{
    wifi_account_t wifi_account;
    while(1)
    {
        if (xQueueReceive(xQueueWifiAccount, &wifi_account, portMAX_DELAY))
        {
            if (wifi_account.back_flag == 1){  // 退出任务标志
                break; // 跳出while循环
            }

            wifi_config_t wifi_config = {
                .sta = {
                .threshold.authmode = WIFI_AUTH_WPA2_PSK,
                .sae_pwe_h2e = WPA3_SAE_PWE_BOTH,
                .sae_h2e_identifier = "",
                },
            };
            strcpy((char*)wifi_config.sta.ssid, wifi_account.wifi_ssid);
            strcpy((char*)wifi_config.sta.password, wifi_account.wifi_password);
            ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
            ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
            ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
                wifi_config.sta.ssid, wifi_config.sta.password);
            esp_wifi_connect();

            /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
            * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
            EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
                    WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
                    pdFALSE,
                    pdFALSE,
                    portMAX_DELAY);

            /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
            * happened. */
            if (bits & WIFI_CONNECTED_BIT) {
                ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
                        wifi_config.sta.ssid, wifi_config.sta.password);
                lvgl_port_lock(0);
                lv_label_set_text(label_wifi_connect, "WLAN连接成功");
                lvgl_port_unlock();
                vTaskDelay(1000 / portTICK_PERIOD_MS); // 给上面的显示一点时间
                lvgl_port_lock(0);
                lv_obj_del(wifi_connect_page); // 删除此页面
                lv_obj_del(wifi_scan_page); // 删除此页面
                lvgl_port_unlock();
                vQueueDelete(xQueueWifiAccount); // 删除队列
                icon_flag = 0; // 标记回到主界面
                xTaskCreatePinnedToCore(get_time_task, "get_time_task", 4 * 1024, NULL, 5, NULL, 0);  // 创建获取时间任务
                break; // 跳出while循环删除任务

            } else if (bits & WIFI_FAIL_BIT) {
                ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
                        wifi_config.sta.ssid, wifi_config.sta.password);
                lvgl_port_lock(0);
                lv_label_set_text(label_wifi_connect, "WLAN连接失败");
                lvgl_port_unlock();
                vTaskDelay(1000 / portTICK_PERIOD_MS); // 给上面的显示一点时间
                lvgl_port_lock(0);
                lv_obj_del(wifi_connect_page); // 删除此页面
                lvgl_port_unlock();
                xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT); // 清除此事件标志位

            } else {
                ESP_LOGE(TAG, "UNEXPECTED EVENT");
                lvgl_port_lock(0);
                lv_label_set_text(label_wifi_connect, "WLAN连接异常");
                lvgl_port_unlock();
                vTaskDelay(1000 / portTICK_PERIOD_MS); // 给上面的显示一点时间
                lvgl_port_lock(0);
                lv_obj_del(wifi_connect_page); // 删除此页面
                lv_obj_del(wifi_scan_page); // 删除此页面
                lvgl_port_unlock();
                wifiset_deinit(); // 清除wifi初始化
            }
        }
    }

    vTaskDelete(NULL);
}

/**
 * @description: 返回主界面按钮事件处理函数
 * @param {lv_event_t} *e
 * @return {*}
 */
static void btn_backmain_cb(lv_event_t *e)
{
    ESP_LOGI(TAG, "btn_backmain Clicked");

    // // 删除wifi扫描界面
    lvgl_port_lock(0);
    lv_obj_del(wifi_scan_page); 
    lvgl_port_unlock();

    // 通知wifi_connect任务退出
    wifi_account_t wifi_account;
    wifi_account.back_flag = 1; 
    xQueueSend(xQueueWifiAccount, &wifi_account, portMAX_DELAY); 
    
    wifiset_deinit();// 清除wifi扫描痕迹
    vQueueDelete(xQueueWifiAccount); // 删除队列
    icon_flag = 0;
}

/**
 * @description: wifi连接
 * @param {void} *arg
 * @return {*}
 */
void app_wifi_connect(void *arg)
{
    vTaskDelay(pdMS_TO_TICKS(200));
    // 扫描WLAN信息
    uint16_t ap_number = DEFAULT_SCAN_LIST_SIZE;
    wifi_ap_record_t ap_info[DEFAULT_SCAN_LIST_SIZE];
    wifi_scan(ap_info, &ap_number);

    lvgl_port_lock(0);

    lv_label_set_text_fmt(label_wifi_scan, "%d WLAN", ap_number);

    // 返回按钮
    lv_obj_t *btn_back = lv_btn_create(obj_title);
    lv_obj_align(btn_back, LV_ALIGN_TOP_LEFT, 0, 0);
    lv_obj_set_size(btn_back, 60, 30);
    lv_obj_set_style_border_width(btn_back, 0, 0); // 设置边框宽度
    lv_obj_set_style_pad_all(btn_back, 0, 0);  // 设置间隙
    lv_obj_set_style_bg_opa(btn_back, LV_OPA_0, 0);
    lv_obj_set_style_shadow_opa(btn_back, LV_OPA_TRANSP, LV_PART_MAIN); // 阴影透明
    lv_obj_add_event_cb(btn_back, btn_backmain_cb, LV_EVENT_CLICKED, NULL);

    lv_obj_t *label_back = lv_label_create(btn_back);
    lv_label_set_text(label_back, LV_SYMBOL_LEFT);
    lv_obj_set_style_text_font(label_back, &lv_font_montserrat_20, 0);
    lv_obj_align(label_back, LV_ALIGN_CENTER, -10, 0);

        // 创建wifi信息列表
    wifi_list = lv_list_create(wifi_scan_page);
    lv_obj_set_size(wifi_list, 320, 200);
    lv_obj_align(wifi_list, LV_ALIGN_TOP_LEFT, 0, 40);
    lv_obj_set_style_border_width(wifi_list, 0, 0);
    lv_obj_set_style_text_font(wifi_list, &font_alipuhui20, 0);
    lv_obj_set_scrollbar_mode(wifi_list,LV_SCROLLBAR_MODE_OFF);  //隐藏wifi_list滚动条
    //btn显示WIFI信息
    lv_obj_t *btn;
    for(int i = 0; i < ap_number; i++)
    {
        ESP_LOGI(TAG, "SSID \t\t%s", ap_info[i].ssid);  // 终端输出wifi名称
        ESP_LOGI(TAG, "RSSI \t\t%d", ap_info[i].rssi);  // 终端输出wifi信号质量
        
        btn = lv_list_add_btn(wifi_list, LV_SYMBOL_WIFI,(const char*)ap_info[i].ssid);
        //LV_SYMBOL_WIFI的字库在font_awesome字体中，没有这句话图标不会正常显示
        lv_obj_t *icon = lv_obj_get_child(btn, 0);
        if (icon) {
            lv_obj_set_style_text_font(icon, &font_awesome, 0);
        }

        lv_obj_add_event_cb(btn, list_btn_cb, LV_EVENT_CLICKED, NULL); //增加btn点击回调函数
    }

    lvgl_port_unlock();

    //创建wifi连接队列和任务
    xQueueWifiAccount = xQueueCreate(2, sizeof(wifi_account_t));
    xTaskCreate(wifi_connect, "wifi_connect", 4*1024, NULL, 5, NULL);
    vTaskDelete(NULL);
}

//  任务函数
static void wifiset_tips_task(void *pvParameters)
{
    // 显示扫描情况
    lvgl_port_lock(0);
    label_wifi_scan = lv_label_create(wifi_scan_page);
    lv_label_set_text(label_wifi_scan, "WLAN 已连接");
    lv_obj_set_style_text_color(label_wifi_scan, lv_color_hex(0x000000), 0); 
    lv_obj_set_style_text_font(label_wifi_scan, &font_alipuhui20, 0);
    lv_obj_align(label_wifi_scan, LV_ALIGN_CENTER, 0, -50);
    lvgl_port_unlock();
    vTaskDelay(500 / portTICK_PERIOD_MS); 
    lvgl_port_lock(0);
    lv_obj_del(wifi_scan_page);
    lvgl_port_unlock();

    vTaskDelete(NULL);
}

/**
 * @description: WIFI应用
 * @return {*}
 */
void wifi_app(void)
{
    static lv_style_t style;
    lv_style_init(&style);
    lv_style_set_radius(&style, 10);
    lv_style_set_opa(&style, LV_OPA_COVER);
    lv_style_set_bg_color(&style, lv_color_hex(0xffffff));
    lv_style_set_border_width(&style, 0);
    lv_style_set_pad_all(&style, 0);
    lv_style_set_width(&style, 320);
    lv_style_set_height(&style, 240);
    
    // 创建一个界面
    wifi_scan_page = lv_obj_create(lv_scr_act());
    lv_obj_add_style(wifi_scan_page, &style, 0);

        // 判断wifi是否已连接
    int isconnect_flag = 1;
    if (s_wifi_event_group != NULL) // 如果创建了此事件组
    {
        // 查看是否已经连接wifi
        EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT, pdFALSE, pdFALSE, 10);
        if (bits & WIFI_CONNECTED_BIT) { // 如果已经连接到wifi
            xTaskCreatePinnedToCore(wifiset_tips_task, "wifiset_tips_task", 2048, NULL, 5, NULL, 0);
        }
        else{
            isconnect_flag = 0;
        } 
    }

    if (s_wifi_event_group == NULL || isconnect_flag == 0) // 没有连接到wifi
    {
        // 创建标题背景
        obj_title = lv_obj_create(wifi_scan_page);
        lv_obj_set_size(obj_title, 320, 40);
        lv_obj_set_align(obj_title, LV_ALIGN_TOP_MID);
        lv_obj_set_style_pad_all(obj_title, 0, 0);  // 设置间隙
        lv_obj_set_style_bg_color(obj_title, lv_color_hex(0x008b8b), 0);

        label_wifi_scan = lv_label_create(obj_title);
        lv_label_set_text(label_wifi_scan, "WLAN扫描中...");
        lv_obj_set_style_text_font(label_wifi_scan, &font_alipuhui20, 0);
        lv_obj_set_style_text_color(label_wifi_scan, lv_color_hex(0xffffff), 0);
        lv_obj_set_align(label_wifi_scan, LV_ALIGN_CENTER);

        icon_flag = 5;

        xTaskCreatePinnedToCore(app_wifi_connect, "app_wifi_connect", 4*1024, NULL, 5, NULL, 0);
    }
}